package com.webex.ta.hydra.gui;

import com.webex.ta.hydra.util.HydraUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-9-9
 * Time: 17:00:25
 */

public class AboutDialog extends JDialog implements ActionListener {

    public AboutDialog(JFrame view) {
        super(view, "About Hydra", true);
        setResizable(false);
        JButton closeBtn = new JButton("Close");
        closeBtn.addActionListener(this);
        getRootPane().setDefaultButton(closeBtn);

        JPanel p = new JPanel(new BorderLayout());
        final AboutPanel aboutPanel = new AboutPanel();
        JPanel flowP = new JPanel(new FlowLayout());
        flowP.add(closeBtn);
        flowP.add(Box.createRigidArea(new Dimension(40, 40)));
        Dimension dim = new Dimension(10, 0);
        p.add(BorderLayout.WEST, Box.createRigidArea(dim));
        p.add(BorderLayout.EAST, Box.createRigidArea(dim));
        p.add(BorderLayout.NORTH, Box.createRigidArea(new Dimension(10, 10)));
        p.add(BorderLayout.SOUTH, flowP);
        p.add(BorderLayout.CENTER, aboutPanel);

//		closeBtn.setToolTipText("");
        closeBtn.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                aboutPanel.handleKeyEvent(e);
            }
        });

        setContentPane(p);
        pack();
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((d.width - getWidth()) / 2, (d.height - getHeight()) / 2);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                closeDialog();
            }
        });
        setVisible(true);
    }



    public void actionPerformed(ActionEvent e) {
        closeDialog();
    }

    private void closeDialog() {
        AboutPanel.stopThread();
        dispose();
    }


    private static class AboutPanel extends JComponent implements Runnable {
        private BufferedImage bufImage;
        private Graphics2D g;
        private static final Font defaultFont = new Font("Dialog", Font.BOLD, 12);
        private final Font bottomLineFont = defaultFont.deriveFont(9.8f);
        private final String sBottomLine;
        private final ImageIcon image;
        private final Vector<String> vLines;
        private static boolean doWork;
        private Thread th;
        private final FontMetrics fm;
        private int iLineHeight = 0, iListHeight, iLineCount = 0,
                iBottomLineXOffset = 0, iBottomLineYOffset = 0,
                iPipeLineCount = 0, w = 0, h = 0, y = 0;
        private static final int
                SLEEP_TIME = 40,
                iBottomPadding = 36,
                iTopPadding = 20;
        private static Rectangle2D.Float rectangle;
        private static GradientPaint gradientPaint;
        private boolean skipDrain = false;

        AboutPanel() {
            sBottomLine = "Hydra Version 0.0.1";
            setFont(defaultFont);
            fm = getFontMetrics(defaultFont);
            FontMetrics fmBottom = getFontMetrics(bottomLineFont);
            iLineHeight = fm.getHeight();
            vLines = new Vector<String>(50);
            image = HydraUtils.getImage("hydra3.jpg");
            MediaTracker tracker = new MediaTracker(this);
            tracker.addImage(image.getImage(), 0);

            try {
                tracker.waitForID(0);
            } catch (Exception exc) {
                tell("AboutPanel: " + exc);
            }

            Dimension d = new Dimension(image.getIconWidth(), image.getIconHeight());
            setSize(d);
            setPreferredSize(d);
            w = d.width;
            h = d.height;
            iBottomLineXOffset = (w / 2) - (fmBottom.stringWidth(sBottomLine) / 2);
            iBottomLineYOffset = h - iLineHeight / 2;
            StringTokenizer st = new StringTokenizer(
                            "Ajax Wang\n" +
                            "Joe Zhang\n" +
                            "Lily Yan\n" +
                            "Matthew Huo\n" +
                            "Sally Tao\n" +
                            "Sky Ye\n" +
                            "Vega Zhou\n",
                    "\n");
            while (st.hasMoreTokens()) {
                vLines.add(st.nextToken());
            }

            iLineCount = vLines.size();
            iListHeight = iLineCount * iLineHeight;
            startThread();
            updateUI();
        }

        private void handleKeyEvent(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                skipDrain = false;
                Collections.rotate(vLines, -1);
            } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                skipDrain = false;
                Collections.rotate(vLines, 1);
            } else if ((e.getKeyCode() == KeyEvent.VK_LEFT) ||
                    (e.getKeyCode() == KeyEvent.VK_RIGHT) ||
                    (e.getKeyCode() == KeyEvent.VK_ESCAPE)) {
                skipDrain = !skipDrain;
            }
        }

        private void drain() {
            if (skipDrain)
                return;
            if (bufImage == null) {
                //pre-computing all data that can be known at this time
                Dimension d = getSize();
                bufImage = new BufferedImage(d.width, d.height,
                        BufferedImage.TYPE_INT_RGB);
                g = bufImage.createGraphics();
                rectangle = new Rectangle2D.Float(0, iTopPadding,
                        d.width, d.height - iBottomPadding - iTopPadding);
                //"+1" makes sure every new line from below comes up smoothly
                //cause it gets pre-painted and clipped as needed
                iPipeLineCount = 1 + (int) Math.ceil(rectangle.height / iLineHeight);
                y = d.height;
                g.setFont(defaultFont);
                gradientPaint = new GradientPaint(
                        rectangle.width / 2, iTopPadding + 30, new Color(40, 40, 40),
                        rectangle.width / 2, iTopPadding, new Color(235, 235, 235)
                );
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            }

            g.drawImage(image.getImage(), 0, 0, w, h, this);
//            g.setColor(Color.white);
//            g.fillRect(0,0,w,h);

            g.setFont(bottomLineFont);

            g.setPaint(new Color(55, 55, 55));
            g.drawString(sBottomLine, iBottomLineXOffset, iBottomLineYOffset);
            // Draw a highlight effect
            g.setPaint(new Color(255, 255, 255, 50));
            g.drawString(sBottomLine, iBottomLineXOffset + 1, iBottomLineYOffset + 1);

            g.setFont(defaultFont);
            g.setPaint(Color.black);


            g.drawRect(0, 0, w - 1, h - 1);
            g.clip(rectangle);
            g.setPaint(gradientPaint);
            int iDrawnLinesCount = 0, yCoor = 0;

            String powerby = "Hydra is powered by:\n";
            g.drawString (powerby, (w - fm.stringWidth(powerby)) / 2, y);
            for (int i = 0; i < iLineCount; i++) {
                //check whether the text line is above the canvas, if so, the code skips it
                yCoor = y + (i + 2) * iLineHeight;
                if (yCoor < iTopPadding) {
                    continue;
                }

                //good to go, now draw only iPipeLineCount lines and get out from loop
                String sLine = vLines.get(i);
                int x = (w - fm.stringWidth(sLine)) / 2;
                g.drawString(sLine, x, yCoor);
                if (++iDrawnLinesCount >= iPipeLineCount) {
                    break;
                }
            }

            y--;
            paint(getGraphics());

            //check if the end of the list has been reached,
            //if so rewind
            if ((y + iListHeight) < iTopPadding) {
                y = h + iBottomPadding;
            }
        }

        @Override
        public void update(Graphics g) {
            paint(g);
        }

        @Override
        public void paint(Graphics panelGraphics) {
            if (panelGraphics != null && bufImage != null) {
                panelGraphics.drawImage(bufImage, 0, 0, w, h, this);
            }
        }

        public void run() {
            try {
                while (doWork) {
                    drain();
                    Thread.sleep(SLEEP_TIME);
                }
            } catch (Exception exc) { }

            doWork = false;
            th = null;
        }

        public void startThread() {
            if (th == null) {
                th = new Thread(this);
                doWork = true;
                th.start();
            }
        }

        public static void stopThread() {
            doWork = false;
        }

        public static void tell(Object obj) {
            String str = obj == null ? "NULL" : obj.toString();
//			JOptionPane.showMessageDialog(jEdit.getActiveView(), str, "Title", 1);
        }
    }
}

